package com.zy.mc_module.utils.retrofit

import android.provider.Settings
import android.webkit.WebSettings
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import com.zy.mc_module.BuildConfig
import com.zy.mc_module.R
import com.zy.mc_module.base.App
import com.zy.mc_module.utils.*
import okhttp3.*
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.io.IOException
import java.io.InputStream
import java.lang.AssertionError
import java.math.BigInteger
import java.security.*
import java.security.cert.CertificateException
import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate
import java.util.*
import java.util.concurrent.TimeUnit
import javax.net.ssl.*

/**
 * Created on 18/10/22
 * 网络请求工具类
 */
class RetrofitManagerKt {//添加头
    //获取Retrofit实例
//TrustManager[] trustManagers = {new MyX509TrustManager()};
    //设置OkhtpClient
//拦截器
    //缓存
    /***
     * 创建Retrofit实例
     */
    private var retrofit: Retrofit? = null
        private get() {
            if (field == null) {
                synchronized(RetrofitManagerKt::class.java) {
                    if (field == null) {
                        //拦截器
                        val loggingInterceptor = HttpLoggingInterceptor(HttpLogger())
                        if (BuildConfig.DEBUG) {
                            loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
                        } else {
                            loggingInterceptor.level = HttpLoggingInterceptor.Level.NONE
                        }
                        //缓存
                        val file = File(App.getInstance().cacheDir, "swy_cache")
                        val cache = Cache(file, 1024 * 1024 * 200)
                        var context: SSLContext? = null
                        //设置OkhtpClient
                        val client = OkHttpClient().newBuilder()
                                .addInterceptor(CacheInterceptor())
                                .addInterceptor(addHeaderInterceptor()) //添加头
                                .addNetworkInterceptor(CacheInterceptor())
                                .cache(cache)
                                .addNetworkInterceptor(loggingInterceptor)
                                //.sslSocketFactory(context!!.socketFactory, trustManager)
                                .hostnameVerifier(TrustAllHostnameVerifier())
                                .connectTimeout(time, TimeUnit.SECONDS)
                                .readTimeout(time, TimeUnit.SECONDS)
                                .writeTimeout(time, TimeUnit.SECONDS)
                                .build()
                        //获取Retrofit实例
                        if (null == AppTools.Base_Url) {
                            AppTools.Base_Url = AppTools.APP_URL_PRETEST
                        }
                        field = Retrofit.Builder().baseUrl(AppTools.Base_Url).client(client)
                                .addConverterFactory(GsonConverterFactory.create())
                                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                                .build()
                    }
                }
            }
            return field
        }
    private val time = 38L

    object RetrofitInstance {
        val instance = RetrofitManagerKt()
            get() = field
    }

    /***
     * 设请求头
     */
    private inner class addHeaderInterceptor : Interceptor {
        @Throws(IOException::class)
        override fun intercept(chain: Interceptor.Chain): Response {
            val original = chain.request()
            val requestBuilder = original.newBuilder()
                    .addHeader("equipment", "android")
                    .removeHeader("User-Agent") //移除旧的
                    .addHeader("User-Agent", WebSettings.getDefaultUserAgent(App.getInstance())) //添加真正的头部
                    .addHeader("uuid", Settings.System.getString(App.getAppContext().contentResolver, Settings.Secure.ANDROID_ID))
                    .addHeader("versionNumber", SystemUtil.getVerName(App.getAppContext()))
            //从request中获取原有的HttpUrl实例oldHttpUrl
            val oldHttpUrl = original.url()
            //从request中获取headers，通过给定的键url_type
            val headerValues = original.headers("url_type")
            if (headerValues != null && headerValues.size > 0) {
                //如果有这个header，先将配置的header删除，因此header仅用作app和okhttp之间使用
                requestBuilder.removeHeader("url_type")
                //匹配获得新的BaseUrl
                val headerValue = headerValues[0]
                var newBaseUrl: HttpUrl? = null
                newBaseUrl = if ("launcher" == headerValue) {
                    HttpUrl.parse(AppTools.Base_Url)
                } else {
                    oldHttpUrl
                }
                //重建新的HttpUrl，修改需要修改的url部分
                val newFullUrl = oldHttpUrl
                        .newBuilder()
                        .scheme(newBaseUrl!!.scheme()) //更换网络协议
                        .host(newBaseUrl.host()) //更换主机名
                        .port(newBaseUrl.port()) //更换端口
                        //                            .removePathSegment(0)//移除第一个参数
                        .build()
                //重建这个request，通过builder.url(newFullUrl).build()；
                // 然后返回一个response至此结束修改
                return chain.proceed(requestBuilder.url(newFullUrl).build())
            }
            val request = requestBuilder.build()
            return chain.proceed(request)
        }
    }

    /***
     * 设置缓存
     * 只对get有用,post没有缓存
     */
    private inner class CacheInterceptor : Interceptor {
        @Throws(IOException::class)
        override fun intercept(chain: Interceptor.Chain): Response {
            var request = chain.request()
            //判断是否有网络
            return if (NetUtil.isNetwork()) {
                val response = chain.proceed(request)
                //有网的时候读接口上的@Headers里的配置，你可以在这里进行统一的设置
                val cacheControl = request.cacheControl().toString()
                val maxAge = 0 //有网时缓存时间
                if (cacheControl.length > 0) {
                    response.newBuilder()
                            .header("Cache-Control", cacheControl)
                            .removeHeader("Pragma")
                            .build()
                } else {
                    response.newBuilder()
                            .removeHeader("Pragma")
                            .removeHeader("Cache-Control")
                            .header("Cache-Control", "public, max-age=$maxAge")
                            .build()
                }
            } else {
                //无网络时,设置缓存超时时间为 10天,只对get有用,post没有缓存
                request = request.newBuilder()
                        .cacheControl(CacheControl.FORCE_CACHE)
                        .build()
                val response = chain.proceed(request)
                val maxStale = 60 * 60 * 24 * 5
                response.newBuilder()
                        .removeHeader("Pragma")
                        .removeHeader("Cache-Control")
                        .header("Cache-Control", "public, only-if-cached, max-stale=$maxStale")
                        .build()
            }
        }
    }

    /***
     * 定义拦截器中的网络日志工具
     */
    private inner class HttpLogger : HttpLoggingInterceptor.Logger {
        override fun log(message: String) {
            Logs.Log_d("Okhttp", message)
        }
    }

    internal inner class TrustAllHostnameVerifier : HostnameVerifier {
        override fun verify(hostname: String, session: SSLSession): Boolean {
            return true
        }
    }

    /***
     * 创建网络接口请求实例
     */
    val api: ApiService
        get() = retrofit!!.create(ApiService::class.java)

    companion object {
        private const val TAG = "RetrofitManager"
    }
}